package mutsumimod.powers;

import com.megacrit.cardcrawl.actions.AbstractGameAction;
import com.megacrit.cardcrawl.actions.common.*;
import com.megacrit.cardcrawl.cards.DamageInfo;
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
import com.megacrit.cardcrawl.monsters.AbstractMonster;
import mutsumimod.util.GeneralUtils;
import mutsumimod.util.TextureLoader;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.megacrit.cardcrawl.core.AbstractCreature;
import com.megacrit.cardcrawl.core.CardCrawlGame;
import com.megacrit.cardcrawl.core.Settings;
import com.megacrit.cardcrawl.helpers.FontHelper;
import com.megacrit.cardcrawl.localization.PowerStrings;
import com.megacrit.cardcrawl.powers.AbstractPower;

public abstract class BasePower extends AbstractPower {

    public void onLoseStand(int standAmount){

    }

    public void betterOnLoseHp(DamageInfo info, int damageAmount) {

    }

    public void getTrueDamageAmount(DamageInfo info, int damageAmount) {

    }

    public void onTriggerStand(int standAmount,int targetAmount) {

    }

    public void gainEnergy(){
        gainEnergy(amount);
    }

    public void gainEnergy(int amount){
        addToBot(new GainEnergyAction(amount));
    }

    public void drawCard(){
        drawCard(amount);
    }

    public void drawCard(int amount) {
        addToBot(new DrawCardAction(AbstractDungeon.player, amount));
    }

    public void damageAllMonster(int baseDamage) {
        damageAllMonster(baseDamage,1, AbstractGameAction.AttackEffect.SLASH_VERTICAL);
    }

    public void damageAllMonster(int baseDamage,int damageTime) {
        damageAllMonster(baseDamage,damageTime,AbstractGameAction.AttackEffect.SLASH_VERTICAL);
    }

    public void damageAllMonster(int baseDamage,int damageTime,AbstractGameAction.AttackEffect effect) {
        for(int i=0;i<damageTime;i++){
            addToBot(new DamageAllEnemiesAction(AbstractDungeon.player, baseDamage, DamageInfo.DamageType.NORMAL , effect));
        }
    }

    public void damageMonster(int damage, AbstractMonster m) {
        damageMonster(damage,m,1, com.megacrit.cardcrawl.actions.AbstractGameAction.AttackEffect.SLASH_VERTICAL);
    }

    public void damageMonster(int damage, AbstractMonster m, int damageTime) {
        damageMonster(damage,m,damageTime,AbstractGameAction.AttackEffect.SLASH_VERTICAL);
    }

    public void damageMonster(int damage, AbstractMonster m, int damageTime, AbstractGameAction.AttackEffect effect) {
        for(int i=0;i<damageTime;i++){
            addToBot(new DamageAction(m, new DamageInfo(AbstractDungeon.player
                    , damage, DamageInfo.DamageType.NORMAL), effect));
        }
    }

    public void gainBlock(){
        gainBlock(amount);
    }

    public void gainBlock(int block){
        addToBot(new GainBlockAction(AbstractDungeon.player, block));
    }

    public void reducePowerAndRemove(int amount,String powerID){
        addToBot(new ReducePowerAction(owner, owner, powerID, amount));
    }


    public void reducePowerAndRemove(int amount,AbstractPower power){
        addToBot(new ReducePowerAction(owner, owner, power, amount));
    }

    public void reducePowerAndRemove(int amount) {
        reducePowerAndRemove(amount,this);
    }

    public void reducePowerAndRemove() {
        reducePowerAndRemove(1);
    }

    public void removePower(String powerID){
        addToBot(new RemoveSpecificPowerAction(owner, owner, powerID));
    }

    public void removePower(AbstractPower power){
        addToBot(new RemoveSpecificPowerAction(owner, owner, power));
    }

    public void removePower(){
        removePower(this);
    }

    public void applyPowerSelf(AbstractPower power){
        applyPowerSelf(power,amount);
    }

    public void applyPowerSelf(AbstractPower power,int magicNumber){
        if(magicNumber==0){
            addToBot(new ApplyPowerAction(AbstractDungeon.player, AbstractDungeon.player, power));
        }else{
            addToBot(new ApplyPowerAction(AbstractDungeon.player, AbstractDungeon.player, power,magicNumber));
        }
    }

    public void applyPowerMonster(AbstractPower power,int magicNumber,AbstractMonster m){
        if(magicNumber==0){
            addToBot(new ApplyPowerAction(m, AbstractDungeon.player, power));
        }else{
            addToBot(new ApplyPowerAction(m, AbstractDungeon.player, power,magicNumber));
        }
    }


    private static PowerStrings getPowerStrings(String ID)
    {
        return CardCrawlGame.languagePack.getPowerStrings(ID);
    }
    protected AbstractCreature source;
    protected String[] DESCRIPTIONS;

    //Will not display if at 0. You can override renderAmount to render it however you want.
    //amount2 will not stack like the normal amount variable when stacking a power.
    public int amount2 = 0;
    protected Color redColor2 = Color.RED.cpy();
    protected Color greenColor2 = Color.GREEN.cpy();

    public BasePower(String id, PowerType powerType, boolean isTurnBased, AbstractCreature owner, int amount) {
        this(id, powerType, isTurnBased, owner, null, amount);
    }
    public BasePower(String id, PowerType powerType, boolean isTurnBased, AbstractCreature owner, AbstractCreature source, int amount) {
        this(id, powerType, isTurnBased, owner, source, amount, true);
    }
    public BasePower(String id, PowerType powerType, boolean isTurnBased, AbstractCreature owner, AbstractCreature source, int amount, boolean initDescription) {
        this(id, powerType, isTurnBased, owner, source, amount, initDescription, true);
    }
    public BasePower(String id, PowerType powerType, boolean isTurnBased, AbstractCreature owner, AbstractCreature source, int amount, boolean initDescription, boolean loadImage) {
        this.ID = id;
        this.isTurnBased = isTurnBased;

        PowerStrings strings = getPowerStrings(this.ID);
        this.name = strings.NAME;
        this.DESCRIPTIONS = strings.DESCRIPTIONS;

        this.owner = owner;
        this.source = source;
        this.amount = amount;
        this.type = powerType;

        if (loadImage)
        {
            String unPrefixed = GeneralUtils.removePrefix(id);
            Texture normalTexture = TextureLoader.getPowerTexture(unPrefixed);
            Texture hiDefImage = TextureLoader.getHiDefPowerTexture(unPrefixed);
            if (hiDefImage != null)
            {
                region128 = new TextureAtlas.AtlasRegion(hiDefImage, 0, 0, hiDefImage.getWidth(), hiDefImage.getHeight());
                if (normalTexture != null)
                    region48 = new TextureAtlas.AtlasRegion(normalTexture, 0, 0, normalTexture.getWidth(), normalTexture.getHeight());
            }
            else
            {
                this.img = normalTexture;
                region48 = new TextureAtlas.AtlasRegion(normalTexture, 0, 0, normalTexture.getWidth(), normalTexture.getHeight());
            }
        }

        if (initDescription)
            this.updateDescription();
    }

    @Override
    public void updateDescription() {
        description = DESCRIPTIONS[0];
    }

    public void renderAmount(SpriteBatch sb, float x, float y, Color c) {
        super.renderAmount(sb, x, y, c);

        if (this.amount2 != 0) {
            if (!this.isTurnBased) {
                float alpha = c.a;
                c = this.amount2 > 0 ? this.greenColor2 : this.redColor2;
                c.a = alpha;
            }

            FontHelper.renderFontRightTopAligned(sb, FontHelper.powerAmountFont, Integer.toString(this.amount2), x, y + 15.0F * Settings.scale, this.fontScale, c);
        }
    }

    public void onChangeStand() {

    }

    public void onChangeStandAmount(int amount) {

    }


}